﻿using System.Xml;
using Basic.WxGatewayModular.Interface;
using Basic.WxGatewayModular.Model;
using Basic.WxRemoteModel.WxMsg;
using Basic.WxRemoteModel.WxMsg.Model;
using WeDonekRpc.Helper;

namespace Basic.WxGatewayModular.lmpl
{
    internal class WxMsgService : IWxMsgService
    {
        private static readonly string[] _FilterMsgs = new string[]
        {
            "ToUserName",
            "CreateTime",
            "FromUserName",
            "MsgType",
            "MsgId",
        };
        private static readonly string[] _FilterEvents = new string[]
        {
            "ToUserName",
            "CreateTime",
            "FromUserName",
            "MsgType",
            "Event",
             "MsgId",
        };
        private readonly IWxPlatformService _Platform;

        public WxMsgService (IWxPlatformService platform)
        {
            this._Platform = platform;
        }

        public void MsgEvent (XmlDocument doc, WxMsgParam param)
        {
            WxPlatform platform = this._Platform.Get(param.PlatformAppId);
            string sign = platform.GetMsgSign(param.Nonce, param.Timestamp);
            if (sign != param.Signature)
            {
                throw new ErrorException("wx.sign.check.fail");
            }
            string xml = platform.Decrypt(doc.FirstChild["Encrypt"].InnerText);
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(xml);
            XmlNode node = doc.FirstChild;
            if (node["MsgType"].InnerText == "event")
            {
                this._WxEventMsg(node, param);
            }
            else
            {
                this._WxMsg(node, param);
            }
        }
        private void _WxEventMsg (XmlNode node, WxMsgParam param)
        {
            WxMsgEventBody msg = new WxMsgEventBody
            {
                MsgId = node["MsgId"].InnerText,
                CreateTime = long.Parse(node["CreateTime"].InnerText),
                EventType = node["Event"].InnerText,
                PlatformAppId = param.PlatformAppId,
                WxAppId = param.WxAppId,
                UserOpenId = node["FromUserName"].InnerText,
                EventBody = []
            };
            foreach (XmlNode i in node.ChildNodes)
            {
                if (!_FilterEvents.Contains(i.Name))
                {
                    msg.EventBody.Add(i.Name, i.InnerText);
                }
            }
            new ReceiveWxEventMsg
            {
                Msg = msg
            }.Send();
        }
        private void _WxMsg (XmlNode node, WxMsgParam param)
        {
            WxMsgBody msg = new WxMsgBody
            {
                MsgId = node["MsgId"].InnerText,
                CreateTime = long.Parse(node["CreateTime"].InnerText),
                MsgType = node["MsgType"].InnerText,
                PlatformAppId = param.PlatformAppId,
                WxAppId = param.WxAppId,
                UserOpenId = node["FromUserName"].InnerText,
                MsgBody = []
            };
            foreach (XmlNode i in node.ChildNodes)
            {
                if (!_FilterMsgs.Contains(i.Name))
                {
                    msg.MsgBody.Add(i.Name, i.InnerText);
                }
            }
            new ReceiveWxMsg
            {
                Msg = msg
            }.Send();
        }
    }
}
